"""
Agent Publish API Routes
Provides endpoints for publishing and unpublishing agents
"""

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from typing import Optional, List

from src.llm.hiagent_app.services.agent_publish_service import AgentPublishService


router = APIRouter(prefix="/api/v1/agent/publish", tags=["Agent Publish"])


# Request/Response Models
class PublishAgentRequest(BaseModel):
    """Request model for publishing an agent"""
    agent_id: str = Field(..., description="Agent ID (AppID)")
    delete_old_keys: bool = Field(True, description="Whether to delete old API keys")
    version: str = Field("1.0.0", description="Version number")
    version_desc: str = Field("Published via API", description="Version description")
    api_key_description: str = Field("Published API Key", description="Description for new API key")
    category_codes: Optional[List[str]] = Field(None, description="Category codes for AppCenter")
    auth_type: str = Field("Public", description="Authorization type (Public/Private)")
    auth_range_type: str = Field("All", description="Authorization range (All/Partial)")
    auto_approve: bool = Field(False, description="Automatically approve the publish request")
    wait_approval: bool = Field(False, description="Wait for publish to complete (requires auto_approve or manual approval)")
    approval_timeout: int = Field(120, description="Timeout for waiting approval completion in seconds")
    enable_api: bool = Field(True, description="Enable API status after publish (default: True)")


class PublishAgentResponse(BaseModel):
    """Response model for publish operation"""
    success: bool
    app_id: str
    new_api_key: str
    new_api_key_id: str
    deleted_keys_count: int
    publish_status: str
    publish_message: str
    publish_id: Optional[str] = None
    approval_id: Optional[str] = None
    approval_success: bool = False
    api_enabled: bool = False


class UnpublishAgentRequest(BaseModel):
    """Request model for unpublishing an agent"""
    agent_id: str = Field(..., description="Agent ID (AppID)")
    delete_api_keys: bool = Field(True, description="Whether to delete all API keys")


class UnpublishAgentResponse(BaseModel):
    """Response model for unpublish operation"""
    success: bool
    app_id: str
    status: str
    message: str
    deleted_keys_count: int = 0
    deleted_keys: List[str] = []


class ErrorResponse(BaseModel):
    """Error response model"""
    success: bool = False
    error: str
    detail: Optional[str] = None


# API Endpoints
@router.post(
    "/publish",
    response_model=PublishAgentResponse,
    summary="Publish Agent with New API Key",
    description="""
    Publish an agent to AppCenter with a new API key.

    This endpoint will:
    1. Optionally delete all old API keys for the agent
    2. Create a new API key
    3. Publish the agent to AppCenter
    4. Optionally auto-approve the publish request
    5. Optionally wait for publish to complete
    6. **Enable API status (APIRunnable) after successful publish (default: true)**
    7. Return the new APPID (same as input) and new API key

    **Auto-Approval Options:**
    - `auto_approve=false, wait_approval=false`: Submit publish request and return immediately (default)
    - `auto_approve=true, wait_approval=false`: Auto-approve but don't wait for completion
    - `auto_approve=true, wait_approval=true`: Auto-approve and wait for publish to complete
    - `auto_approve=false, wait_approval=true`: Wait for manual approval to complete

    **API Status:**
    - `enable_api=true` (default): Automatically enable API status after successful publish
    - `enable_api=false`: Do not enable API status (agent will remain in "stopped" state)

    If approval is required and auto_approve is false, the response will include an approval_id
    and status will be 'pending_approval'.
    """
)
async def publish_agent(request: PublishAgentRequest):
    """
    Publish an agent with a new API key

    Args:
        request: PublishAgentRequest containing agent_id and publish options

    Returns:
        PublishAgentResponse with new API key and publish status

    Raises:
        HTTPException: If publishing fails
    """
    try:
        service = AgentPublishService()

        result = service.publish_with_new_key(
            app_id=request.agent_id,
            delete_old_keys=request.delete_old_keys,
            version=request.version,
            version_desc=request.version_desc,
            api_key_description=request.api_key_description,
            auto_approve=request.auto_approve,
            wait_approval=request.wait_approval,
            approval_timeout=request.approval_timeout,
            enable_api=request.enable_api
        )

        return PublishAgentResponse(
            success=True,
            app_id=result["app_id"],
            new_api_key=result["new_api_key"],
            new_api_key_id=result["new_api_key_id"],
            deleted_keys_count=result["deleted_keys_count"],
            publish_status=result["publish_status"],
            publish_message=result["publish_message"],
            publish_id=result.get("publish_id"),
            approval_id=result.get("approval_id"),
            approval_success=result.get("approval_success", False),
            api_enabled=result.get("api_enabled", False)
        )

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to publish agent: {str(e)}"
        )


@router.post(
    "/unpublish",
    response_model=UnpublishAgentResponse,
    summary="Unpublish Agent by Deleting API Keys",
    description="""
    Unpublish an agent by deleting all its API keys.

    This endpoint will:
    1. List all API keys for the agent
    2. Delete all API keys (if delete_api_keys=true)
    3. Return the count of deleted keys

    **Note:** This does NOT call any publish/unpublish API.
    It simply removes the API keys to prevent API access.
    """
)
async def unpublish_agent(request: UnpublishAgentRequest):
    """
    Unpublish an agent by deleting its API keys

    Args:
        request: UnpublishAgentRequest containing agent_id and options

    Returns:
        UnpublishAgentResponse with deleted keys info

    Raises:
        HTTPException: If unpublishing fails
    """
    try:
        service = AgentPublishService()

        result = service.unpublish_agent(
            app_id=request.agent_id,
            delete_api_keys=request.delete_api_keys
        )

        return UnpublishAgentResponse(
            success=True,
            app_id=result["app_id"],
            status=result["status"],
            message=result["message"],
            deleted_keys_count=result.get("deleted_keys_count", 0),
            deleted_keys=result.get("deleted_keys", [])
        )

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to unpublish agent: {str(e)}"
        )


@router.get(
    "/keys/{agent_id}",
    summary="List Agent API Keys",
    description="List all API keys for a specific agent"
)
async def list_agent_keys(agent_id: str):
    """
    List all API keys for an agent

    Args:
        agent_id: Agent ID (AppID)

    Returns:
        List of API key information

    Raises:
        HTTPException: If listing fails
    """
    try:
        service = AgentPublishService()
        keys = service.list_api_keys(agent_id)

        return {
            "success": True,
            "agent_id": agent_id,
            "keys_count": len(keys),
            "keys": keys
        }

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to list API keys: {str(e)}"
        )


@router.delete(
    "/keys/{api_key_id}",
    summary="Delete Agent API Key",
    description="Delete a specific API key by its ID"
)
async def delete_agent_key(api_key_id: str):
    """
    Delete an API key

    Args:
        api_key_id: API Key ID to delete

    Returns:
        Success status

    Raises:
        HTTPException: If deletion fails
    """
    try:
        service = AgentPublishService()
        service.delete_api_key(api_key_id)

        return {
            "success": True,
            "api_key_id": api_key_id,
            "message": "API key deleted successfully"
        }

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to delete API key: {str(e)}"
        )
